package com.glsc.ngateway.platform.controller.itflow;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.common.dto.PageQueryParamDto;
import com.glsc.ngateway.common.api.flowable.dto.FlowDoTaskRespDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamStopDto;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.AbstractFindByIdParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.AbstractRejectParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.system.SystemPassParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.vendor.VendorRateFlowCreateParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.vendor.VendorRateTaskFormDataDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.vendor.domaindto.VendorRateMainFormDto;
import com.glsc.ngateway.common.api.flowable.resp.FlowableResponse;
import com.glsc.ngateway.common.api.flowable.resp.ResponseSituationDto;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrDeptDto;
import com.glsc.ngateway.common.api.ldap.feign.IFeignLdapService;
import com.glsc.ngateway.common.api.ldap.resp.AppEhrResponse;
import com.glsc.ngateway.common.api.platform.resp.PlatformResponse;
import com.glsc.ngateway.common.api.flowable.resp.ResponseMsgDto;
import com.glsc.ngateway.common.base.domain.mysql.gateway.ldap.LdapEhrDept;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormVendorRateMain;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowEnum;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.platform.service.FlowCommonService;
import com.glsc.ngateway.platform.service.itflow.ItFlowService;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.vendor.VendorRateFlowStrategy;
import com.glsc.ngateway.platform.service.vendor.VendorRateDetailService;
import com.glsc.ngateway.platform.utils.RequestTool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author xuchang
 */
@RestController
@RequestMapping(value = "/it/flow/vendorRate/")
@Api(value = "供应商评价流程", tags = {"供应商评价流程接口"})
public class VendorRateFlowController {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private ItFlowService itFlowService;
    @Value("${spring.profiles.active}")
    private String active;

    @Resource
    private RequestTool requestTool;

    @Resource
    private VendorRateFlowStrategy vendorRateFlowStrategy;

    @Resource
    private VendorRateDetailService vendorRateDetailService;

    @Resource
    private IFeignLdapService iFeignLdapService;

    @Resource
    private ThreadPoolTaskExecutor threadPool;
    @Resource
    private FlowCommonService flowCommonService;


    /**
     * 流程发起
     *
     * @param param 流程创建表单数据
     */
    @ApiOperation(value = "流程发起", notes = "流程发起")
    @PostMapping(value = "/createFlow")
    public PlatformResponse<FlowDoTaskRespDto> createFlow(@RequestBody VendorRateFlowCreateParamDto<VendorRateMainFormDto, VendorRateTaskFormDataDto> param) throws Exception {
        String operatorStart = requestTool.getAccountFromRequest();
        FlowDoTaskRespDto respDto = itFlowService.createFlow(param, operatorStart, ITFlowEnum.VENDOR_RATE.getKey());
        return PlatformResponse.successData(respDto);
    }

    /**
     * 保存节点数据，但是不提交任务
     */
    @ApiOperation(value = "保存节点数据", notes = "保存节点数据")
    @PostMapping("/saveFormData")
    public PlatformResponse<FlowDoTaskRespDto> saveFormData(@RequestBody VendorRateFlowCreateParamDto<VendorRateMainFormDto, VendorRateTaskFormDataDto> param) throws Exception {
        String operatorStart = requestTool.getAccountFromRequest();
        FlowDoTaskRespDto respDto = itFlowService.saveFormData(param, operatorStart, ITFlowEnum.VENDOR_RATE.getKey());
        return PlatformResponse.successData(respDto);
    }

    /**
     * 审核通过
     */
    @ApiOperation(value = "审核通过", notes = "流程审核处理通过")
    @PostMapping("/taskAuditPass")
    public PlatformResponse<FlowDoTaskRespDto> taskAuditPass(@RequestBody SystemPassParamDto<VendorRateMainFormDto, VendorRateTaskFormDataDto> param) throws Exception {
        String operatorStart = requestTool.getAccountFromRequest();
        FlowDoTaskRespDto respDto = itFlowService.taskAuditPass(param, operatorStart, ITFlowEnum.VENDOR_RATE.getKey());
        return PlatformResponse.successData(respDto);
    }

    /**
     * 流程内删除按钮
     * 终止该条流程 数据还在 限于供应商评价
     */
    @ApiOperation(value = "流程内删除", notes = "流程内删除")
    @PostMapping("/taskAuditDelete")
    public PlatformResponse<FlowDoTaskRespDto> taskAuditDelete(@RequestBody SystemPassParamDto<VendorRateMainFormDto, VendorRateTaskFormDataDto> param) throws Exception {
        String operatorStart = requestTool.getAccountFromRequest();
        FlowDoTaskRespDto respDto = itFlowService.taskAuditPass(param, operatorStart, ITFlowEnum.VENDOR_RATE.getKey());
        return PlatformResponse.successData(respDto);
    }

    /**
     * 团队长批量审批
     * 审核通过
     */
    @ApiOperation(value = "批量审核通过", notes = "流程审核处理通过")
    @PostMapping("/batchTaskAuditPass")
    public PlatformResponse<String> batchTaskAuditPass(@RequestBody List<String> taskIdlist) throws Exception {
        String operatorStart = requestTool.getAccountFromRequest();
        //判断是否是团队长
        if ("pro".equals(active)) {
            if("0".equals(isDepLeader(operatorStart))){
                throw PlatformException.errorWithOutMail("只允许团队长批量审批");
            }
        }
        itFlowService.batchAudit(taskIdlist,operatorStart);
        return PlatformResponse.successData("批量审核中，请关注审核结果");
    }

    /**
     * 流程发起人是否是团队长，
     * 是则直接提交结束，否则提交给团队长审批
     * @param flowCreaterOA
     * @return
     */
    public String isDepLeader(String flowCreaterOA){
        //给节点处理人赋予处理人，如果当前人员是团队长，则跳过团队长审批节点
        AppEhrResponse<LdapEhrDeptDto> depResp = iFeignLdapService.getDepByAccount(flowCreaterOA);
        if (Objects.isNull(depResp) || depResp.getStatus() != 0) {
            throw PlatformException.error("未找到部门信息");
        }
        LdapEhrDept depInfo = JSONObject.parseObject(JSONObject.toJSONString(depResp.getData()), LdapEhrDept.class);
        String leader = depInfo.getLeader();
        //默认员工
        String isDLeader = "1";
        boolean b = !"二级部门".equals(depInfo.getDepgrade());
        boolean blank = Strings.isBlank(leader);
        boolean b1 = !leader.equals(flowCreaterOA);
        logger.info("三个判断:{}-{}-{}", b, blank, b1);
        if (b || blank || b1) {
            //特殊情况，团队长审批节点跳过
            isDLeader =  "0";
        }
        return isDLeader;
    }

    /**
     * 审核驳回
     */
    @Deprecated
    @ApiOperation(value = "审核驳回，返回至起始节点", notes = "流程审核驳回处理")
    @PostMapping("/taskAuditReject")
    public PlatformResponse<FlowableResponse<ResponseMsgDto>> taskAuditReject(@RequestBody AbstractRejectParamDto taskDto) throws PlatformException {
        FlowableResponse<ResponseMsgDto> respDto = itFlowService.taskAuditReject(taskDto, requestTool.getAccountFromRequest(), ITFlowEnum.VENDOR_RATE.getKey());
        return PlatformResponse.successData(respDto);
    }

    /**
     * 根据流程实例ID或者任务ID检索流程
     */
    @ApiOperation(value = "根据流程实例ID或者任务ID检索流程", notes = "根据流程实例ID或者任务ID检索流程状态、备注等，如提供流程实例ID则认为只读方式获取数据")
    @PostMapping("/findByProcessIdOrTaskId")
    public PlatformResponse<VendorRateFlowCreateParamDto<VendorRateMainFormDto, VendorRateTaskFormDataDto>> findByProcessIdOrTaskId(@RequestBody AbstractFindByIdParamDto param) {
        VendorRateFlowCreateParamDto<VendorRateMainFormDto, VendorRateTaskFormDataDto> context = new VendorRateFlowCreateParamDto<>();
        itFlowService.getWorkFlowFormByTaskId(param, ITFlowEnum.VENDOR_RATE.getKey(), context);
        return PlatformResponse.successData(context);
    }



    @ApiOperation(value = "流程分页查询", notes = "流程分页查询")
    @PostMapping("/findPage")
    public PlatformResponse<Page<VendorRateMainFormDto>> findPage(
            @ApiParam(value = "查询参数") @RequestBody PageQueryParamDto<VendorRateMainFormDto> queryParamDto) {
        Page<VendorRateMainFormDto> page = vendorRateFlowStrategy.findPage(queryParamDto);
        return PlatformResponse.successData(page);
    }

    @ApiOperation(value = "供应商评价初始化", notes = "供应商评价初始化")
    @PostMapping("/genInit")
    public PlatformResponse<String> genInit() {
        new Thread(() -> {
            logger.info("供应商评价初始化");
            vendorRateDetailService.createVendorFlowTask();
        }).start();
        return PlatformResponse.successMsg("OK");
    }


    @ApiOperation(value = "供应商评价每日通知", notes = "供应商评价每日通知")
    @PostMapping("/genRemindInit")
    public PlatformResponse<String> genRemindInit() {
        new Thread(() -> {
            logger.info("供应商评价每日通知初始化");
            vendorRateDetailService.notifyVendor(null);
        }).start();
        return PlatformResponse.successMsg("OK");
    }


    @ApiOperation(value = "流程强制结束操作", notes = "流程强制结束操作")
    @PostMapping("/processStop")
    public PlatformResponse<FlowableResponse> processStop(@RequestBody ParamStopDto paramStopDto) throws Exception {
        logger.info("流程强制结束操作,paramStopDto=" + paramStopDto);
        String processId = paramStopDto.getProcessId();
        if(StrUtil.isBlank(processId)){
            throw PlatformException.errorWithOutMail("请传入processId");
        }
        String deleteResason = paramStopDto.getDeleteReason();
        if(StrUtil.isBlank(deleteResason)){
            throw PlatformException.errorWithOutMail("请输入删除原因");
        }

        ResponseSituationDto processInfo = flowCommonService.getProcessInfo(processId);
        if (Objects.isNull(processInfo) || processInfo.getProcessDefineKey().isBlank()) {
            return PlatformResponse.failedMsg("流程审批通过操作失败:未找到流程信息");
        } else {//更新流程form表单中的结束状态
            FlowFormVendorRateMain byProcessId = vendorRateFlowStrategy.findByProcessId(processId);
            if(StrUtil.isNotBlank(byProcessId.getDeleteResason())){
                logger.info("当前流程已经删除，{}",byProcessId);
                throw PlatformException.errorWithOutMail("当前流程已经完成删除归档");
            }
            itFlowService.processStop(paramStopDto, processInfo.getProcessDefineKey(), requestTool.getAccountFromRequest());
            byProcessId.setDeleteResason(deleteResason);
            vendorRateFlowStrategy.save(byProcessId);
        }
        FlowableResponse ret = flowCommonService.processStop(paramStopDto);
        return PlatformResponse.successData(ret);
    }
}
